﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SocialPlatformSDK.Services.Util;
using SocialPlatformSDK.Util;

namespace SocialPlatformSDK.Model
{
    public abstract class IOAuthConfigruation
    {
        public string APP_KEY { get; set; }

        /// <summary>
        /// 获取或设置你的应用的 App Secret.
        /// </summary>
        public string APP_SECRET { get; set; }

        /// <summary>
        /// 获取腾迅微博 Open API 的根地址.
        /// </summary>
        /// <remarks>
        /// 默认为 http://open.t.qq.com/api/
        /// </remarks>
        public string Authority { get; set; }

        /// <summary>
        /// 获取或设置所希望 API 返回的数据格式.
        /// </summary>
        /// <remarks>
        /// 默认为 Json
        /// </remarks>
        public DataFormat Format { get; set; }

        /// <summary>
        /// 获取或设置当前用户的 AccessToken.
        /// </summary>
        /// <remarks>若 IfSaveAccessToken == true, 则请不要手动设置该值.</remarks>
        public AccessToken AccessToken { get; set; }

        public CodeToken CodeToken { get; set; }
        /// <summary>
        /// 获取或设置当前用户的 AccessToken 保存文件.
        /// </summary>
        /// <remarks>若 IfSaveAccessToken == true, 则请不要手动设置该值.</remarks>
        public SafeIsolatedStorage<AccessToken> TokenIso { get; set; }

        /// <summary>
        /// 获取或设置在用户授权成功后，是否需要 SDK 帮助你储存用户的 AccessToken.
        /// </summary>
        /// <remarks>
        /// true, SDK 将管理 AccessToken, 请不要手动设置 AccessToken.
        /// false，请手动设置 AccessToken， 或者在实例化 Service 时，调用带 AccessToken 参数的构造函数.
        /// </remarks>
        public bool IfSaveAccessToken { get; set; }

        /// <summary>
        /// 清除缓存中和正在使用的 Access Token.
        /// </summary>
        public abstract void ClearAccessToken();


        /// <summary>
        /// 验证 OAuth 相关的配置信息.
        /// </summary>
        /// <remarks>
        /// 1. Authority, AppKey, AppSerect 不允许为空，否则会抛出异常.
        /// 2. 若 IfSaveAccesstoken == true, SDK 将尝试从用户储存空间中读取 AccessToken，
        /// 若未找到 AccessToken, 则会抛出 MissingAppKeyOrAppSecretException 异常.
        /// 3. 若 IfSaveAccessToken ==  false,  则不会验证 AccessToken.
        /// </remarks>
        public abstract void Validate();

        public static readonly IOAuthConfigruation Instance ;

        public abstract void Init();



        public string APIUrl { get; protected set; }

        public string TokenUrl { get; protected set; }

        public string RedirectUri { get; protected set; }

        public string LoginAuth { get; protected set; }

        public string OAuthUri { get; protected set; }

        public string GetRequestToken { get; protected set; }

        public string GetAccessToken { get; protected set; }

        public string CallBackUrl { get; protected set; }

        public string Accredit { get; protected set; }
    }

    public abstract class OAuthConfigruationBase<T> : IOAuthConfigruation
        where T:IOAuthConfigruation,new ()
    {

        /// <summary>
        /// 配置必须单例
        /// </summary>
        public new static readonly T Instance = new T();

        public override void ClearAccessToken()
        {
            TokenIso.Clear();
            
            AccessToken = null;
        }
        public override void Validate()
        {
            if (string.IsNullOrEmpty(APP_KEY) || string.IsNullOrEmpty(APP_SECRET))
            {
                throw new MissingAppKeyOrAppSecretException();
            }
            
            if (string.IsNullOrEmpty(Authority))
            {
                throw new OAuthException("Authority 不能为空!");
            }

            if (IfSaveAccessToken)
            {
                AccessToken token = TokenIso.LoadData();

                if (null == token)
                {
                    throw new MissingAccessTokenExcception();
                }


                if (token == null || string.IsNullOrEmpty(token.AccesssToken) )
                {
                    throw new MissingAccessTokenExcception();
                }

                AccessToken = token;
            }
        }
   
    }
}
